﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Sinacor.Infra.Service.Data;
using PSE.ProcessManager.Server.Process.Security;
using Sinacor.Infra.Core.ProcessManager.Server.Security;
using System.Data.Common;
using System.Data;
using Sinacor.Infra.Service.Common;

namespace Sinacor.Process.Bovespa.Distribuicao.Server.ResourceAccess
{
    public class Importacao : BaseResourceAccess 
    {
        #region Construtor

        public Importacao()
            : base(AuthenticationContext<SinacorAuthenticationData>.Current.AuthenticationData.CompanyId)
        {
        }

        #endregion

        #region Métodos Públicos

        public int LimparTabelaImportacao()
        {
            int retorno;

            string sqlCommand = "TRUNCATE TABLE TORDISIMP REUSE STORAGE ";

            using (DbCommand command = this.DataBase.GetSqlStringCommand(sqlCommand))
            {
                retorno = this.DataBase.ExecuteNonQuery(command);
            }

            return retorno;
        }

        public int ImportarDistribuicao(ProcessEntity.DistribuicaoDetail entity)
        {
            int retorno;

            string sqlCommand = @"INSERT INTO TORDISIMP (CD_CODNEG, 
                                                         CD_CLIENTE,  
                                                         QT_NEGOCIO,
                                                         VL_NEGOCIO, 
                                                         CD_NATOPE,   
                                                         CD_CARLIQ,
                                                         CD_USUARIO, 
                                                         CD_CLIFIM,   
                                                         DV_CLIFIM,
                                                         IN_LIQUIDA, 
                                                         CD_BOLSAMOV, 
                                                         PC_REDACR,
                                                         TP_VCOTER, 
                                                         NR_SEQORD) 
                                  VALUES (:CodigoISIN,
                                          :CodigoCliente,
                                          :Quantidade,
                                          :PrecoNegocio,
                                          :NaturezaOperacao,
                                          :CarteiraLiquidacao,
                                          :CustArbitragem,
                                          :ClienteCustArbitragem,
                                          :DigitoCustArbitragem,
                                          :TipoLiquidacao,
                                          :BolsaNegocio,
                                          :PercentualAcrescimo,
                                          :PrazoTermo,
                                          :NumeroOrdem)";

            using (DbCommand command = this.DataBase.GetSqlStringCommand(sqlCommand))
            {
                this.DataBase.AddInParameter(command, "CodigoISIN", DbType.String, entity.CodigoISIN);
                this.DataBase.AddInParameter(command, "CodigoCliente", DbType.String, entity.CodigoCliente);
                this.DataBase.AddInParameter(command, "Quantidade", DbType.Decimal, entity.Quantidade);
                this.DataBase.AddInParameter(command, "PrecoNegocio", DbType.Decimal, entity.PrecoNegocio);
                this.DataBase.AddInParameter(command, "NaturezaOperacao", DbType.String, EnumConverter.ToString<ProcessEntity.Enum.NaturezaOperacao>(entity.NaturezaOperacao));
                this.DataBase.AddInParameter(command, "CarteiraLiquidacao", DbType.Int16, entity.CarteiraLiquidacao);
                this.DataBase.AddInParameter(command, "CustArbitragem", DbType.Int32, entity.CustodianteArbitragem);
                this.DataBase.AddInParameter(command, "ClienteCustArbitragem", DbType.Int32, entity.ClienteCustodianteArbitragem);
                this.DataBase.AddInParameter(command, "DigitoCustArbitragem", DbType.Int16, entity.DigitoCustodianteArbitragem);
                this.DataBase.AddInParameter(command, "TipoLiquidacao", DbType.String, EnumConverter.ToString<ProcessEntity.Enum.TipoLiquidacao>(entity.TipoLiquidacao));
                this.DataBase.AddInParameter(command, "BolsaNegocio", DbType.String, EnumConverter.ToString<ProcessEntity.Enum.BolsaNegocio>(entity.BolsaNegocio));
                this.DataBase.AddInParameter(command, "PercentualAcrescimo", DbType.Decimal, entity.PercentualAcrescimo);
                this.DataBase.AddInParameter(command, "PrazoTermo", DbType.Int32, entity.PrazoTermo);
                this.DataBase.AddInParameter(command, "NumeroOrdem", DbType.Int64, entity.NumeroOrdem);

                retorno = Convert.ToInt32(this.DataBase.ExecuteNonQuery(command));
            }

            return retorno;
        }

        public List<ProcessEntity.Broker> ConsultarBrokersImportados(ProcessEntity.Parameter.FiltroBrokersImportados entity)
        {
            List<ProcessEntity.Broker> retorno = null;

            StringBuilder sqlCommand = new StringBuilder(@"SELECT DISTINCT(B.CD_CLIENTE_LIQFIN) as CodigoBroker
                                                           FROM TORDISIMP A,
                                                                TSCCLIBOL B ");

            if (entity.TipoDistribuicao == ProcessEntity.Enum.TipoFormaDistribuicao.Apelido)
            {
                sqlCommand.AppendLine(" WHERE RTRIM( A.CD_CLIENTE, ' ' ) = B.NM_APELIDO ");
            }
            else
            {
                sqlCommand.AppendLine(" WHERE A.CD_CLIENTE = B.CD_CLIENTE ");
            }

            using (DbCommand command = this.DataBase.GetSqlStringCommand(sqlCommand.ToString()))
            {
                retorno = this.FindAll<ProcessEntity.Broker>(command,
                                                             reader =>
                                                             {
                                                                 ProcessEntity.Broker item = new ProcessEntity.Broker();

                                                                 item.CodigoBroker = reader.GetValue<int>("CodigoBroker");

                                                                 return item;
                                                             });
            }

            return retorno;
        }

        public ProcessEntity.Resultado ProcessarDistribuicao(ProcessEntity.Parameter.FiltroProcessamentoDistribuicao entity)
        {
            ProcessEntity.Resultado retorno = null;
            StringBuilder sqlCommand = new StringBuilder();

            sqlCommand.Append(" DECLARE rettype BOOLEAN; ");
            sqlCommand.Append(" BEGIN ");
            sqlCommand.Append(" rettype:= PR_MONTA_DISTRI.fOr_Distri_A (:DataMovimento, :DataPregao, :TipoCliente, :TipoDistribuicao, :TipoAlgoritmo, 1, :R_nErro, :R_sErro, :R_sArgs); ");
            sqlCommand.Append(" IF rettype THEN :R_Retorno := 1; ELSE :R_Retorno := 0; END IF; ");
            sqlCommand.Append(" END; ");

            using (DbCommand command = this.DataBase.GetSqlStringCommand(sqlCommand.ToString()))
            {
                this.DataBase.AddInParameter(command, "DataMovimento", DbType.String, entity.DataMovimento.ToString("dd/MM/yyyy"));
                this.DataBase.AddInParameter(command, "DataPregao", DbType.String, entity.DataMovimento.ToString("dd/MM/yyyy"));
                this.DataBase.AddInParameter(command, "TipoCliente", DbType.String, EnumConverter.ToString<ProcessEntity.Enum.TipoFormaDistribuicao>(entity.TipoDistribuicao.Value));
                this.DataBase.AddInParameter(command, "TipoDistribuicao", DbType.String, EnumConverter.ToString<ProcessEntity.Enum.TipoDistribuicao>(entity.Header.TipoDistribuicao.Value));
                this.DataBase.AddInParameter(command, "TipoAlgoritmo", DbType.String, EnumConverter.ToString<ProcessEntity.Enum.TipoDistribuicaoPrecoMedio>(entity.TipoDistribuicaoPrecoMedio.Value));

                this.DataBase.AddOutParameter(command, "R_nErro", DbType.Int32, 4);
                this.DataBase.AddOutParameter(command, "R_sErro", DbType.String, 1000);
                this.DataBase.AddOutParameter(command, "R_sArgs", DbType.String, 2000);
                this.DataBase.AddOutParameter(command, "R_Retorno", DbType.Int32, 4);

                this.DataBase.ExecuteNonQuery(command);

                retorno = new ProcessEntity.Resultado();

                if (Convert.ToBoolean(this.DataBase.GetParameterValue(command, "R_Retorno")))
                {
                    retorno.Sucesso = true;
                }
                else
                {
                    retorno.Sucesso = false;
                    retorno.CodigoErro = Convert.ToInt32(this.DataBase.GetParameterValue(command, "R_nErro"));
                    retorno.Argumentos = Convert.ToString(this.DataBase.GetParameterValue(command, "R_sArgs"));
                }
            }

            return retorno;
        }

        #endregion
    }
}
